#ifndef __CSVECTOR_H__
#define __CSVECTOR_H__

template<class T>
class CSVectorOperation
{
public:
	static inline void Construct(T* Array,int n)
	{
		for(int i=0;i<n;i++)
		{
			new(Array+i) T();
		}
	}
	static inline void Construct(T* ToArray,const T* FromArray)
	{
		new(ToArray) T(*FromArray);
	}
	static inline void Construct(T* ToArray,const T* FromArray,int n)
	{
		for(int i=0;i<n;i++)
		{
			Construct(ToArray+i,FromArray+i);
		}
	}
	static inline void Destruct(T* t)
	{
		t->~T();
	}
	static inline void Destruct(T* Array,int n)
	{
		for(int i=0;i<n;i++)
		{
			Destruct(Array+i);
		}
	}
	static inline void Copy(T* ToArray,const T* FromArray,int n)
	{
		Construct(ToArray,FromArray,n);
	}
	static inline void Move(T* ToArray,const T* FromArray,int n)
	{
		if(n<=0)
			return ;
		if(ToArray>FromArray)
		{
			for(int i=n-1;i>=0;i--)
			{
				Construct(ToArray+i,FromArray+i);
			}
		}
		else if(ToArray<FromArray)
		{
			Construct(ToArray,FromArray,n);
		}
	}
};

template<class T,class Mem,int InitNum>
class CSVectorBase
{
	typedef CSVectorOperation<T> Op;
public:
	class iterator
	{
	public:
		iterator(){mBaseData=0;mIndex=-1;}
		explicit iterator(T* Base,int Index){mBaseData=Base;mIndex=Index;}
		iterator(const iterator &iter){mBaseData=iter.mBaseData;mIndex=iter.mIndex;}
		iterator& operator=(const iterator &iter) {mBaseData=iter.mBaseData;mIndex=iter->mIndex;}
		bool operator==(const iterator& iter) {return (mBaseData==iter.mBaseData&&mIndex==iter.mIndex);}
		bool operator!=(const iterator& iter) {return (mBaseData!=iter.mBaseData||mIndex!=iter.mIndex);}
		iterator& operator++() {mIndex++;return *this;}
		iterator& operator--() {mIndex--;return *this;}
		T& operator*() {return mBaseData[mIndex];}
		T* operator->() {return mBaseData+mIndex;}
	public:
		int mIndex;
		T* mBaseData;
	};
public:
	CSVectorBase() {Init();}
	~CSVectorBase() {Release();}
public:
	void Init()
	{
		mTotalNum=InitNum;
		mNowSize=0;
		mData=Malloc(InitNum);
	}
	void Release()
	{
		Clear();
		Free(mData);
	}
	T* Malloc(int num) 
	{
		return (T*)Mem::Malloc(num*sizeof(T));
	}
	void Free(T* t) {Mem::Free((void*)t);}

	iterator Insert(int Pos,const T& t);
	iterator Erase(const iterator& iter);
	void Clear()
	{
		mNowSize=0;
	}

	iterator Begin() {return iterator(mData,0);}
	iterator End() {return iterator(mData,mNowSize);}

	int GetSize() {return mNowSize;}
	bool Reserve(int size);
	void Resize(int size);
	bool Empty() {return mNowSize==0;}
	T& Front() {return mData[0];}
	void PushFront(const T& t);
	void PopFront();
	T& Back() {return mData[mNowSize-1];}
	void PushBack(const T& t);
	void PopBack();
	void Remove(int index);
	
	T& operator[](int n) const
	{
		if(n>=mNowSize)
		{
			return *((T*)0);
		}
		return mData[n];
	}
protected:
	int mTotalNum;
	int mNowSize;
	T* mData;
};

template<class T,class Mem,int InitNum>
bool CSVectorBase<T,Mem,InitNum>::Reserve(int size)
{
	T* tmp = Malloc(size);
	if(!tmp)
		return false;
	Op::Construct(tmp,mData,(size>mNowSize?mNowSize:size));
	Op::Destruct(mData,mNowSize);
	Free(mData);
	mTotalNum=size;
	mData = tmp;
	if(mNowSize>size)
		mNowSize=size;
	return true;
}

template<class T,class Mem,int InitNum>
void CSVectorBase<T,Mem,InitNum>::Resize(int size)
{
	if(size>mTotalNum)
	{
		if(!Reserve(size))
			return ;
	}
	if(size>mNowSize)
		Op::Construct(mData+mNowSize,size-mNowSize);
	mNowSize=size;
}

template<class T,class Mem,int InitNum>
typename CSVectorBase<T,Mem,InitNum>::iterator CSVectorBase<T,Mem,InitNum>::Insert(int Pos,const T& t)
{
	if(mNowSize>=mTotalNum)
	{
		if(Reserve(mTotalNum*2))
			return End();
	}
	Op::Move(mData+Pos+1,mData+Pos,mNowSize-Pos);
	Op::Construct(mData+Pos,&t);
	mNowSize++;
	
	return iterator(mData,Pos);
}

template<class T,class Mem,int InitNum>
typename CSVectorBase<T,Mem,InitNum>::iterator CSVectorBase<T,Mem,InitNum>::Erase(const typename CSVectorBase<T,Mem,InitNum>::iterator& iter)
{
	Op::Destruct(*iter);
	Op::Move(mData+iter.mIndex,mData+iter.mIndex+1,mNowSize-iter.mIndex-1);
	--mNowSize;
	return iter;
}

template<class T,class Mem,int InitNum>
void CSVectorBase<T,Mem,InitNum>::PushFront(const T& t)
{
	Insert(0,t);
}

template<class T,class Mem,int InitNum>
void CSVectorBase<T,Mem,InitNum>::PopFront()
{
	Erase(Begin());
}

template<class T,class Mem,int InitNum>
void CSVectorBase<T,Mem,InitNum>::PushBack(const T& t)
{
	Insert(mNowSize,t);
}

template<class T,class Mem,int InitNum>
void CSVectorBase<T,Mem,InitNum>::PopBack()
{
	Erase(iterator(mData,mNowSize-1));
}

template<class T,class Mem,int InitNum>
void CSVectorBase<T,Mem,InitNum>::Remove(int index)
{
	Erase(iterator(mData,index));
}


#endif

